package com.zondy.mapgis.android.utils;

import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.drawable.BitmapDrawable;
import android.location.Address;
import android.location.Geocoder;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.MeasureSpec;
import android.widget.Toast;

import com.zondy.mapgis.android.annotation.Annotation;
import com.zondy.mapgis.android.gpx.bean.Waypoint;
import com.zondy.mapgis.android.graphic.GraphicMultiPoint;
import com.zondy.mapgis.android.graphic.GraphicPolylin;
import com.zondy.mapgis.android.mapview.MapView;
import com.zondy.mapgis.android.mapview.MapView.MapViewStopCurRequestCallback;
import com.zondy.mapgis.core.geometry.Dot;
import com.zondy.mapgis.core.geometry.Rect;
import com.zondy.mapgis.core.spatial.SpaCalculator;

public class MapUtil
{

	public static MapUtil mapUtil;
	public static String TAG = MapUtil.class.getSimpleName();

	android.location.Geocoder androidGeocoder;

	private MapUtil()
	{
	}

	public static MapUtil getInstance()
	{
		if (mapUtil == null)
		{
			mapUtil = new MapUtil();
		}
		return mapUtil;
	}

	/**
	 * android系统自带的地理编码，地名转化为坐标，此转化方式为同步阻塞方式，直接返回结果
	 * 
	 * @param context
	 * @param keyWords
	 * @param resultMaxCount
	 * @return
	 */
	public List<Address> androidGeoCode(Context context, String keyWords, int resultMaxCount)
	{
		if (androidGeocoder == null)
		{
			androidGeocoder = new Geocoder(context, Locale.getDefault());
		}
		List<Address> result = null;
		try
		{
			result = androidGeocoder.getFromLocationName(keyWords, resultMaxCount);

		}
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * android系统自带的地理反编码，坐标转化为地名，此转化方式为同步阻塞方式，直接返回结果
	 * 
	 * @param context
	 * @param keyWords
	 * @param resultMaxCount
	 * @return
	 */
	public List<Address> androidReverseGeoCode(Context context, double longitude, double latitude, int resultMaxCount)
	{
		if (androidGeocoder == null)
		{
			androidGeocoder = new Geocoder(context, Locale.getDefault());
		}
		List<Address> result = null;
		try
		{
			result = androidGeocoder.getFromLocation(latitude, longitude, resultMaxCount);
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		return result;
	}

	// ========
	/**
	 * 从本地文件加载地图
	 * 
	 * @param mapView
	 * @param mapFilePath
	 */
	public void loadMap(Context context, MapView mapView, String mapFilePath)
	{
		if (mapView == null)
		{
			showDialog(context, "mapView 控件为空");
			return;
		}
		if (TextUtils.isEmpty(mapFilePath))
		{
			showDialog(context, "地图路径为空");
			return;
		}
		File file = new File(mapFilePath);
		if (!file.exists())
		{
			showDialog(context, "地图文件不存在");
			return;
		}
		mapView.loadFromFile(mapFilePath);

	}
	
	/**
	 * 当地图数据发生变化时调动此放法 (这个方法有问题，当stop时做改变地图图层状态，改变地图数据的方法)
	 * 
	 * @param mapview
	 */
	public static void updateMap(final MapView mapview)
	{
		mapview.stopCurRequest(new MapViewStopCurRequestCallback()
		{

			@Override
			public void onDidStopCurRequest()
			{
				mapview.forceRefresh();
			}
		});

	}

	/**
	 * 添加单个annotation
	 * 
	 * @param context
	 * @param title
	 * @param jsonDescription
	 * @param latitude
	 * @param longitude
	 * @param imgResourceId 标注的图片id
	 * @return
	 */
	public static Annotation addAnnotation(Context context, MapView mapView, String uid, String title, String jsonDescription, double longitude,
			double latitude, int imgResourceId)
	{
		Bitmap bmp = ((BitmapDrawable) context.getResources().getDrawable(imgResourceId)).getBitmap();
		return addAnnotation(context, mapView, uid, title, jsonDescription, latitude, longitude, bmp);
	}

	/**
	 * 添加标注
	 * 
	 * @param context
	 * @param mapView
	 * @param uid
	 * @param title
	 * @param jsonDescription
	 * @param latitude
	 * @param longitude
	 * @param bitmap
	 * @return
	 */
	public static Annotation addAnnotation(Context context, MapView mapView, String uid, String title, String jsonDescription, double longitude,
			double latitude, Bitmap bitmap)
	{
		// Dot dot = Lonlat2Mercator(longitude, latitude,0);
		if (latitude > 0 && longitude > 0)
		{
			Dot dot = PointTransferUtil.Lonlat2Mercator(new Dot(longitude, latitude));
			Annotation annotation;
			// 添加地图标注
			if (!TextUtils.isEmpty(uid))
			{
				annotation = new Annotation(uid, title, jsonDescription, dot, bitmap);
			}
			else
			{
				annotation = new Annotation(title, jsonDescription, dot, bitmap);
			}
			mapView.getAnnotationsOverlay().addAnnotation(annotation);
			return annotation;
		}
		else
		{
			Toast.makeText(context, "经纬度有误", Toast.LENGTH_SHORT).show();
			return null;
		}
	}

	/**
	 * 添加多个标注
	 * 
	 * @param mapView
	 * @param annotations
	 * @return
	 */
	public static List<Annotation> addAnnotations(MapView mapView, List<Annotation> annotations)
	{
		mapView.getAnnotationsOverlay().addAnnotations(annotations);
		return annotations;
	}

	/**
	 * 添加单个标注(通过点)
	 * 
	 * @param context
	 * @param mapView
	 * @param uid
	 * @param title
	 * @param jsonDescription
	 * @param dot
	 * @param bitmap
	 */
	public static Annotation addAnnotionByDot(Context context, MapView mapView, String uid, String title, String jsonDescription, Dot dot, Bitmap bitmap)
	{
		Annotation annotation;
		// 添加地图标注
		if (!TextUtils.isEmpty(uid))
		{
			annotation = new Annotation(uid, title, jsonDescription, dot, bitmap);
		}
		else
		{
			annotation = new Annotation(title, jsonDescription, dot, bitmap);
		}
		annotation.setCenterOffset(new Point(0, -12));
		mapView.getAnnotationsOverlay().addAnnotation(annotation);
		// annotation.showAnnotationView();
		mapView.refresh();
		return annotation;
	}

	/**
	 * 地图缩放到指定范围,将所有指定点都显示在地图中。
	 * 
	 * @param context
	 * @param mapView
	 * @param dots
	 */
	public static void zoomToRange(Context context, MapView mapView, List<Dot> dotMapPoints)
	{
		if (dotMapPoints == null || dotMapPoints.size() <= 0)
		{
			showDialog(context, "集合列表为空");
			return;
		}
		ArrayList<Double> xList = new ArrayList<Double>();
		ArrayList<Double> yList = new ArrayList<Double>();
		for (Dot dot : dotMapPoints)
		{
			double x = dot.x;
			double y = dot.y;

			xList.add(x);
			yList.add(y);
		}
		double xMin = 0;
		double xMax = 0;
		double yMin = 0;
		double yMax = 0;
		for (int i = 0; i < xList.size(); i++)
		{
			double xCurrent = xList.get(i);
			double yCurrent = yList.get(i);
			if (i == 0)
			{
				xMin = xMax = xCurrent;
				yMin = yMax = yCurrent;
			}
			else
			{
				xMin = xMin < xCurrent ? xMin : xCurrent;
				xMax = xMax > xCurrent ? xMax : xCurrent;
				yMin = yMin < yCurrent ? yMin : yCurrent;
				yMax = yMax > yCurrent ? yMax : yCurrent;
			}
		}
		if (xMax > 180)
		{
			Rect rect = new Rect(xMin - 300, yMin - 300, xMax + 300, yMax + 300);
			// mapView.zoomToRange(rect, true);
			mapView.zoomToRange(rect, false);
		}
		else
		{
			Rect rect = new Rect(xMin, yMin, xMax, yMax);
			// mapView.zoomToRange(rect, true);
			mapView.zoomToRange(rect, false);
		}

	}

	/**
	 * 扩大Rect的范围
	 * 
	 * @param rect
	 * @return
	 */
	public static Rect zoomRect(Rect rect)
	{
		Rect zoomRect = new Rect();
		;
		if (rect.xMax > 180 || rect.yMax > 180)
		{
			zoomRect = new Rect(rect.xMin - 200, rect.yMin - 200, rect.xMax + 200, rect.yMax + 200);
		}

		return zoomRect;
	}

	/**
	 * 像素转地图距离
	 * 
	 * @param mapview
	 * @param px
	 * @return
	 */
	public static Float pxToMapDis(MapView mapview, float px)
	{
		float dis = 0.0f;
		PointF point1 = new PointF(0.0f, 0.0f);
		PointF point2 = new PointF(px, 0.0f);
		Dot dot1 = mapview.viewPointToMapPoint(point1);
		Dot dot2 = mapview.viewPointToMapPoint(point2);
		dis = (float) (dot2.x - dot1.x);

		return dis;

	}

	/**
	 * dialog弹出信息提示
	 * 
	 * @param context
	 * @param msg
	 */
	public static void showDialog(Context context, String msg)
	{
		AlertDialog.Builder builder = new AlertDialog.Builder(context);
		final AlertDialog dialog = new AlertDialog.Builder(context).create();
		builder.setTitle("提示");
		builder.setMessage(msg);
		builder.setPositiveButton("确定", new DialogInterface.OnClickListener()
		{

			@Override
			public void onClick(DialogInterface arg0, int arg1)
			{
				dialog.dismiss();
			}
		});
		dialog.show();
	}

	/**
	 * 判断dot2距离centerDot1是否小于distance
	 * 
	 * @param dot1
	 * @param dot2
	 * @param distance
	 * @return
	 */
	public boolean isInRange(Dot centerDot1, Dot dot2, double distance)
	{
		if (distance <= 0)
		{
			return true;
		}
		if (dotDistance(centerDot1, dot2) < distance)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	/**
	 * 计算两点之间的距离
	 * 
	 * @param dot1
	 * @param dot2
	 * @return
	 */
	public static double dotDistance(Dot dot1, Dot dot2)
	{
		try
		{
			Dot dot11 = new Dot();
			Dot dot22 = new Dot();
			
			if(dot1.x < 180 && dot1.x > -180 && dot2.y < 90 && dot2.y > -90)
			{
				dot11 = PointTransferUtil.Lonlat2Mercator(dot1);
				dot22 = PointTransferUtil.Lonlat2Mercator(dot2);
				return SpaCalculator.distance(dot11, dot22);
			}
			else
			{
				return SpaCalculator.distance(dot1, dot2);
			}
		}
		catch (Exception e)
		{
			return 0;
		}
	}

	public static double dotsDistance(List<Dot> dotlst)
	{
		double ditance = 0.0;
		if (dotlst.size() > 1)
		{
			// ditance
		}

		return ditance;

	}

	/**
	 * 从多个annotation中找出与给定的annotation，并改变它的图标
	 * 
	 * @param context
	 * @param mapView
	 * @param annotations
	 * @param annotation
	 * @param fromImgResourceId
	 * @param toImgResourceId
	 */
	public void updateAnnotation(Context context, MapView mapView, List<Annotation> annotations, Annotation annotation, int fromImgResourceId,
			int toImgResourceId)
	{
		Bitmap bmpFrom = ((BitmapDrawable) context.getResources().getDrawable(fromImgResourceId)).getBitmap();
		Bitmap bmpTo = ((BitmapDrawable) context.getResources().getDrawable(toImgResourceId)).getBitmap();
		for (Annotation anno : annotations)
		{
			if (anno.getPoint().x == annotation.getPoint().x && anno.getPoint().y == annotation.getPoint().y)
			{
				anno.setImage(bmpTo);
			}
			else
			{
				anno.setImage(bmpFrom);
			}
		}
		mapView.refresh();
	}

	public void showSelectAnnotationView(Context context, MapView mapView, List<Annotation> annotations, Annotation annotation)
	{

		for (Annotation anno : annotations)
		{
			if (anno.getPoint().x == annotation.getPoint().x && anno.getPoint().y == annotation.getPoint().y)
			{
				anno.showAnnotationView();
			}
			else
			{
				anno.hideAnnotationView();
			}
		}
		mapView.refresh();

	}

	/**
	 * view转化为Bitmap
	 */
	public static Bitmap convertViewToBitmap(View view)
	{
		view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
		view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
		view.buildDrawingCache();
		Bitmap bitmap = view.getDrawingCache();
		return bitmap;
	}

	/**
	 * 在地图上添加轨迹
	 * 
	 * @param mapview
	 * @param graphicMultiPoint
	 * @param graphicPolylin
	 * @param waypoints
	 */
	public static void drawTracksOnMap(Context context, MapView mapView, GraphicMultiPoint graphicMultiPoint, GraphicPolylin graphicPolylin, List<Dot> mapDotLst)
	{
		graphicPolylin.removeAllPoints();
		graphicMultiPoint.removeAllPoints();

		if (mapDotLst == null)
		{
			return;
		}
		// you wenti 空指针异常
		if (mapDotLst.size() == 0 || mapDotLst == null)
		{
			return;
		}
		graphicMultiPoint.setPoints(mapDotLst);
		graphicPolylin.setPoints(mapDotLst);
		// test
		// Dot[] dots = new Dot[mapDotLst.size()];
		// for(int i = 0; i < mapDotLst.size();i++)
		// {
		// dots[i] = mapDotLst.get(i);
		// }
		// graphicMultiPoint.appendPoints(dots);
		// graphicPolylin.appendPoints(dots);

		if (mapDotLst.size() > 2 && mapDotLst.size() < 6)
		{
			zoomToRange(context, mapView, mapDotLst);
		}
		mapView.refresh();

	}

	/**
	 * 把WayPoints转化为地图Dots
	 * 
	 * @param waypoints
	 * @return
	 */
	public static List<Dot> wayPointsToMapDotLst(Context context, ArrayList<Waypoint> waypoints)
	{
		if (waypoints.size() == 0 || waypoints == null)
		{
			return null;
		}
		List<Dot> dotLst = new ArrayList<Dot>();
		for (int i = 0; i < waypoints.size(); i++)
		{
			Dot lonlat = new Dot(waypoints.get(i).getLongitude(), waypoints.get(i).getLatitude());
			// lonlat = convertGpxToAMap(context, CoordType.GPS, lonlat);
			// 转魔卡托
			Dot dot = PointTransferUtil.Lonlat2Mercator(lonlat);
			// 火星坐标系 (GCJ-02) to GPS84
			// GPS gps = PositionUtil.gcj_To_Gps84(lonlat.y, lonlat.x);
			// Dot dot = new Dot(gps.getWgLon(), gps.getWgLat());
			dotLst.add(dot);
		}

		return dotLst;
	}

	/**
	 * 采集当前点和上一个点是否相等
	 * 
	 * @param curWayPoint
	 * @param lastWayPoint
	 * @return
	 */
	public static boolean isEqual(Waypoint curWayPoint, Waypoint lastWayPoint)
	{
		double curLat = curWayPoint.getLatitude();
		double curLon = curWayPoint.getLongitude();
		double lat = lastWayPoint.getLatitude();
		double lon = lastWayPoint.getLongitude();

		// 这个条件判断没想通
		if (curWayPoint.getLatitude() == lastWayPoint.getLatitude() && curWayPoint.getLongitude() == lastWayPoint.getLongitude())
		{
			Log.d(TAG, "true");
		}
		if (curLat == lat && curLon == lon)
		{
			return true;
		}
		else
		{
			return false;
		}

	}

	/**
	 * 采集当前点和上一个点相比是否偏移过大（0.001）
	 * 
	 * @param curWayPoint
	 * @param lastWayPoint
	 * @return
	 */

	public static boolean isDeviate(Waypoint curWayPoint, Waypoint lastWayPoint)
	{
		if (Math.abs(curWayPoint.getLatitude() - lastWayPoint.getLatitude()) > 0.001
				|| Math.abs(curWayPoint.getLongitude() - lastWayPoint.getLongitude()) > 0.001)
		{

		}
		return false;

	}

	/**
	 * double转化为6个小数的字符串
	 * 
	 * @param doubleValue
	 * @return
	 */
	public static String formatLocation(double doubleValue)
	{
		DecimalFormat decimalFormat = (DecimalFormat) NumberFormat.getInstance();
		decimalFormat.setMaximumFractionDigits(6);
		return decimalFormat.format(Double.valueOf(doubleValue));
	}
	/**
	 * GPS原始坐标转化为高德地图坐标
	 * 
	 * @param context
	 * @param type
	 * @param lonlat
	 */
	// public static Dot convertGpxToAMap(Context context,CoordType type,Dot
	// lonlat)
	// {
	// //初始化坐标转换类
	// CoordinateConverter converter = new CoordinateConverter(context);
	// converter.from(type);
	// //设置需要转换的坐标
	// DPoint examplePoint = new DPoint(lonlat.y,lonlat.x);
	// try
	// {
	// converter.coord(examplePoint);
	// //转换成高德坐标
	// DPoint destPoint = converter.convert();
	// if(null != destPoint){
	// lonlat = new Dot(destPoint.getLongitude(), destPoint.getLatitude());
	// } else {
	// Log.d(TAG, "坐标转换失败");
	// }
	//
	// }
	// catch (Exception e)
	// {
	// Log.d(TAG, "坐标转换失败");
	// e.printStackTrace();
	// }
	// return lonlat;
	//
	// }
}
